'''
xgboost分类器
# 使用卷积神经网络输出的特征作为输入
# 只对第一类和第二类做分类（腺癌和鳞癌）,并绘制ROC曲线
# 每个分类器通过调整二分类阈值可生成一条ROC曲线
'''

import xgboost as xgb
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from data_analysis.data_two_metrics import auc_curve, pr_curve


# 一般：无wh,无特殊坐标
def train():
    # train_features, test_features, train_labels, test_labels = read_data2()

    # 读取数据
    train_features = np.load('D:/lung_cancer/pytorch_code/two_result/xgboost_train_features.npy')
    # print(train_features.shape)
    train_labels = np.load('D:/lung_cancer/pytorch_code/two_result/xgboost_train_labels.npy')

    test_features = np.load('D:/lung_cancer/pytorch_code/two_result/xgboost_test_features.npy')
    test_labels = np.load('D:/lung_cancer/pytorch_code/two_result/xgboost_test_labels.npy')





    dtrain = xgb.DMatrix(train_features, label=train_labels)
    dtest = xgb.DMatrix(test_features, label=test_labels)

    param = {
        'booster': 'gbtree',
        'objective': 'binary:logistic',  # 二分类问题
        'eval_metric': 'logloss',
        'max_depth': 6,               # 构建树的深度， 越大越容易过拟合
        'lambda': 12,                   # 控制模型复杂度的权重值L2正则化项参数， 参数越大， 模型越不容易过拟合
        'subsample': 1,                # 随机采样训练样本
        'colsample_bytree': 0.7,       # 生成树时进行的列采样
        'min_child_weight': 2,         # 孩子节点中最小的样本权重和。如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束。在现行回归模型中，这个参数是指建立每个模型所需要的最小样本数。该参数越大算法越conservative
        'eta': 0.4,                    # 如同学习率
        'seed': 0,
        'nthread': 4,                  # cpu线程数
        'slient': 1
    }

    # 循环次数
    num_round = 10
    watchlist = [(dtrain, 'train')]
    model = xgb.train(param, dtrain, num_boost_round=num_round, evals=watchlist)

    # 可视化特征重要性
    # xgb.plot_importance(model)
    # plt.savefig('../output/features_importance.png')
    # plt.show()
    # plt.close()

    # 可视化模型
    # img1 = xgb.to_graphviz(model, num_trees=0)
    # img1.format = 'png'
    # img1.view('../output/img1')

    # 保存模型
    # model.save_model('../output/model.json')
    # 导出模型和特征映射
    # model.dump_model('../output/model.txt')

    # 测试
    train_preds =model.predict(dtrain)

    print(train_preds)

    test_preds = model.predict(dtest)

    # 保存测试集结果（概率值）
    # np.save('D:/lung_cancer/data/two_result/two_xgboost_labels.npy', test_labels)
    # np.save('D:/lung_cancer/data/two_result/two_xgboost_preds.npy', test_preds)

    # 绘制roc曲线
    auc_curve(test_labels, test_preds)
    auc_curve(train_labels, train_preds)
    # pr_curve(test_labels, test_preds)
    # pr_curve(train_labels, train_preds)


if __name__ == '__main__':
    train()
